package com.ch.engine.utils.aes2;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

@Slf4j
public class DataEncryptUtils {

    /** 👇👇👇👇👇👇👇👇👇👇👇👇👇自定义加密👇👇👇👇👇👇👇👇👇👇👇👇👇 */


    /**
     * F
     * 加盐字符
     */
    public static final String ENCRYPT_PLAINTEXT = "osHwxCAndFxwSc";

    /**
     * 加密方法   加盐加随机数  返回加密字符串
     **/
    public static String encode(String code) {
        int random = (int) ((Math.random() * 9 + 1) * 100);
        code = random + code;

        byte[] codeBytes = code.getBytes();
        for (int i = 0; i < codeBytes.length; i++) {
            codeBytes[i] = (byte) (codeBytes[i] ^ 'a');
        }
        String data = new String(codeBytes);
        byte[] b = data.getBytes();
        //遍历
        for (int i = 0; i < b.length; i++) {
            b[i] += 1;//在原有的基础上+1
        }
        //给密文加盐
        return ENCRYPT_PLAINTEXT + new String(b);
    }

    /**
     * 解密方法  去除加密字符串   返回解密字符
     **/
    public static String decode(String data) {
        //截取到原有的密文
        data = data.substring(ENCRYPT_PLAINTEXT.length(), data.length());
        //把字符串转为字节数组
        byte[] b = data.getBytes();
        //遍历
        for (int i = 0; i < b.length; i++) {
            b[i] -= 1;//在原有的基础上-1
        }
        String code = new String(b);
        byte[] a = code.getBytes();
        for (int i = 0; i < a.length; i++) {
            a[i] = (byte) (a[i] ^ 'a');
        }
        String decodeData = new String(a);
        return decodeData.substring(3, decodeData.length());
    }


    /** 👇👇👇👇👇👇👇👇👇👇👇👇👇AES加密👇👇👇👇👇👇👇👇👇👇👇👇👇 */

    /**
     * AES加密  使用秘钥进行AES加密      privateKey必须为长度16位(否则会报错哦)
     **/
    public static String encryptAES(String data, String privateKey) {
        try {
            data = encodeAES(data);
            byte[] bytes = data.getBytes();
            IvParameterSpec ivParameterSpec = new IvParameterSpec("HWXCFX==20200907".getBytes());
            SecretKeySpec secretKeySpec = new SecretKeySpec(privateKey.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            bytes = cipher.doFinal(bytes);
            bytes = Base64.getEncoder().encode(bytes);
            return new String(bytes);
        } catch (Exception e) {
            log.error("XXXX：data= {},key={}", data, privateKey);
            log.error(e.getMessage(), e);
            return null;
        }
    }

    /**
     * AES解密  使用秘钥进行AES解密    privateKey必须为长度16位(否则会报错哦)
     **/
    public static String decryptAES(String data, String privateKey) {
        try {
            byte[] bytes = Base64.getDecoder().decode(data);
            IvParameterSpec ivParameterSpec = new IvParameterSpec("HWXCFX==20200907".getBytes());
            SecretKeySpec secretKeySpec = new SecretKeySpec(privateKey.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
            bytes = cipher.doFinal(bytes);
            String result = new String(bytes);
            return decodeAES(result);
        } catch (Exception e) {
            log.error("XXXXX：data= {},key={}", data, privateKey);
            log.error(e.getMessage(), e);
            return null;
        }
    }


    public static String encodeAES(String code) {
        byte[] codeBytes = code.getBytes();
        for (int i = 0; i < codeBytes.length; i++) {
            codeBytes[i] = (byte) (codeBytes[i] ^ 'a');
        }
        String data = new String(codeBytes);
        byte[] b = data.getBytes();
        //遍历
        for (int i = 0; i < b.length; i++) {
            b[i] += 1;//在原有的基础上+1
        }
        //给密文加盐
        return ENCRYPT_PLAINTEXT + new String(b);
    }

    public static String decodeAES(String data) {
        //截取到原有的密文
        data = data.substring(ENCRYPT_PLAINTEXT.length(), data.length());
        //把字符串转为字节数组
        byte[] b = data.getBytes();
        //遍历
        for (int i = 0; i < b.length; i++) {
            b[i] -= 1;//在原有的基础上-1
        }
        String code = new String(b);
        byte[] a = code.getBytes();
        for (int i = 0; i < a.length; i++) {
            a[i] = (byte) (a[i] ^ 'a');
        }
        return new String(a);
    }

    //47oKPEAneQuZJpMD95ROK0NhMuq71AxjBofFKSbAejw=   Ms5J66kPK/LgXoyHZJv5wBu2XfW6OJKc5uPXL/k0Wbo=

    public static void main(String[] args) {
        //数据加密开始
//        System.out.println("解密:" + decryptAES("47oKPEAneQuZJpMD95ROK0NhMuq71AxjBofFKSbAejw=", "vwceJf5MrhQsUfpB"));
        System.out.println("加密：" + encryptAES("456", "1234567891234567"));
        System.out.println("解密：" + decryptAES("CbYDGap+z3ixPBiHKdpKYse6PgX3ZEOGlOXslmWTryo=", "1234567891234567"));
    }
}